﻿using System.Xml.Serialization;

namespace Baggr.FeedParser.Atom
{
    using System;
    using System.Xml;

    /// <summary>
    /// Стили текста.
    /// </summary>
    public class AtomTextStyles
    {
        /// <summary>
        /// Используемый стиль.
        /// </summary>
        private readonly TextStyle _Style;

        /// <summary>
        /// Единственный используемый экземпляр "размеченного" текста.
        /// </summary>
        private static AtomTextStyles _Html = new AtomTextStyles(TextStyle.Html);

        /// <summary>
        /// Единственный используемый экземпляр "обычного" текста.
        /// </summary>
        private static AtomTextStyles _Text = new AtomTextStyles(TextStyle.Text);

        /// <summary>
        /// Единственный используемый экземпляр текста в формате "xhtml".
        /// </summary>
        private static AtomTextStyles _Xhtml = new AtomTextStyles(TextStyle.Xhtml);

        /// <summary>
        /// Конструктор класса.
        /// </summary>
        /// <param name="style">
        /// Используемый стиль.
        /// </param>
        private AtomTextStyles(TextStyle style)
        {
            _Style = style;
        }

        /// <summary>
        /// Типы текстов.
        /// </summary>
        private enum TextStyle
        {
            /// <summary>
            /// Текст размечен.
            /// </summary>
            [XmlEnum("html")]
            Html,

            /// <summary>
            /// Обычный текст.
            /// </summary>
            [XmlEnum("text")]
            Text,

            /// <summary>
            /// Текст в формате xhtml
            /// </summary>
            [XmlEnum("xhtml")]
            Xhtml
        }

        /// <summary>
        /// Текст размечен.
        /// </summary>
        public static AtomTextStyles Html
        {
            get
            {
                return _Html;
            }
        }

        /// <summary>
        /// Обычный текст.
        /// </summary>
        public static AtomTextStyles Text
        {
            get
            {
                return _Text;
            }
        }

        /// <summary>
        /// Обычный текст.
        /// </summary>
        public static AtomTextStyles Xhtml
        {
            get
            {
                return _Xhtml;
            }
        }

        /// <summary>
        /// значение по-умолчанию.
        /// </summary>
        public static AtomTextStyles Deffault
        {
            get
            {
                return Text;
            }
        }

        /// <summary>
        /// Экземпляр является "размеченным".
        /// </summary>
        public bool IsHtml
        {
            get
            {
                return _Style == TextStyle.Html;
            }
        }

        /// <summary>
        /// Экземпляр является "обычным" тестом.
        /// </summary>
        public bool IsText
        {
            get
            {
                return _Style == TextStyle.Text;
            }
        }

        /// <summary>
        /// Экземпляр является текстом в формате Xhtml.
        /// </summary>
        public bool IsXhtml
        {
            get
            {
                return _Style == TextStyle.Xhtml;
            }
        }

        /// <summary>
        /// Распарсить строку.
        /// </summary>
        /// <param name="value">
        /// Строка, которую необходимо распарсить.
        /// </param>
        /// <returns>
        /// Тип значение.
        /// </returns>
        public static AtomTextStyles Parse(string value)
        {
            if (value == null)
                return Deffault;

            switch (value.ToUpper())
            {
                case "TEXT":
                    return Text;
                case "HTML":
                    return Html;
                case "XHTML":
                    return Xhtml;
                default:
                    return Deffault;
            }
        }

        /// <summary>
        /// Получить элемент из аттрибута "type".
        /// Если параметр не определен, то выбирается значение по-умолчанию.
        /// </summary>
        /// <param name="element">
        /// Исслудемый элемент.
        /// </param>
        /// <returns>
        /// Значние по значению аттрибута, а иначе значение по-умолчанию.
        /// </returns>
        public static AtomTextStyles GetFromXmlElement(XmlElement element)
        {
            if (element == null)
                throw new ArgumentNullException("element");
            var typeAttribute = element.GetAttribute("type");
            return Parse(typeAttribute);
        }
    }
}
